package com.job.admin.message.service.impl;

import cn.hutool.log.Log;
import com.alibaba.fastjson2.JSON;
import com.job.admin.message.pojo.ConnectItem;
import com.job.admin.message.pojo.Message;
import com.job.admin.message.pojo.MessageItem;
import com.job.admin.message.service.MessageService;
import com.job.client.common.exception.MyselfException;
import com.job.client.common.minio.BucketNameConstant;
import com.job.client.common.minio.MinIOUtils;
import com.job.client.common.result.AppHttpCode;
import com.job.client.common.result.ResponseResult;
import com.job.client.common.utils.DateTimeUtils;
import com.job.client.model.message.constant.ChatLogRabbitmqConstant;
import com.job.feign.admin.audit.AuditFeign;
import com.job.feign.client.auth.AuthFeign;
import com.job.feign.client.message.MessageFeign;
import com.job.feign.webSocket.WebSocketFeign;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import com.job.admin.message.constant.MessageConstant;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

@Service
@Slf4j
public class MessageServiceImpl implements MessageService {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private AuthFeign authFeign;
    @Autowired
    private AuditFeign auditFeign;
    @Autowired
    private MessageFeign messageFeign;
    @Autowired
    private WebSocketFeign webSocketFeign;
//    TODO：用户创建的时候调用此函数，自动初始化消息列表
    @Override
    public ResponseResult createMessage(String messageId) {
        if(messageId == null){
            return ResponseResult.ErrorResult(AppHttpCode.DATA_NULL);
        }
        Message message =new Message();
        message.setUserId(messageId);

        List<ConnectItem> connectItemList = new ArrayList<>();
        ConnectItem connectItem =new ConnectItem();
        connectItem.setUserId(MessageConstant.DEFAULT_USER_ID);
        connectItem.setNumber(MessageConstant.NUMBER_INIT);

        List<MessageItem> messageItemList = new ArrayList<>();
        MessageItem messageItem =new MessageItem();
        messageItem.setTime(DateTimeUtils.createNowTime());
        messageItem.setType(MessageConstant.MESSAGE_TYPE_TEXT);
        messageItem.setContent(MessageConstant.DEFAULT_MESSAGE);
        messageItem.setStatus(MessageConstant.CONTENT_OTHER_STATUS);
        messageItemList.add(messageItem);

        connectItem.setMessage(messageItemList);
        connectItemList.add(connectItem);

        message.setConnect(connectItemList);

        mongoTemplate.save(message);
        return ResponseResult.OkResult();
    }
//    TODO
    @Override
    public ResponseResult createConnect(String messageId,String connectId,MessageItem messageItem) {
        if(messageItem == null || connectId == null){
            return ResponseResult.ErrorResult(AppHttpCode.DATA_NULL);
        }
        // 查找是否存在当前会话，如果存在就插入记录，否则创建
        Query query = new Query(Criteria.where("user_id").is(messageId)
                .and("connect.user_id").is(connectId));
        Message message = mongoTemplate.findOne(query, Message.class);
        if(message == null){
            List<MessageItem> messageItemList = new ArrayList<>();
            messageItem.setStatus(MessageConstant.CONTENT_OTHER_STATUS);
            messageItem.setTime(DateTimeUtils.createNowTime());
            messageItemList.add(messageItem);
            ConnectItem connectItem = new ConnectItem(connectId,MessageConstant.NUMBER_INIT,messageItemList);

            Query query1 = new Query(Criteria.where("user_id").is(messageId));
            Update update = new Update().push("connect", connectItem);
            mongoTemplate.findAndModify(query1, update, Message.class);
        }else{
            ResponseResult result = saveMessage(messageId, connectId, messageItem);
            if(result.getCode() != 200){
                return result;
            }
        }
        return ResponseResult.OkResult();
    }

    @Override
    public ResponseResult saveMessage( String messageId, String connectId,MessageItem messageItem) {
        if(messageItem == null || messageId == null || connectId == null){
            return ResponseResult.ErrorResult(AppHttpCode.DATA_NULL);
        }

        // 发送webSocket
        Map<String,Object> webSocketData = new HashMap<>();
        webSocketData.put("messageItem",messageItem);
        webSocketData.put("userId",connectId);
        pushMessage(messageId,JSON.toJSONString(webSocketData));

        Query queryMy = new Query(Criteria.where("user_id").is(messageId)
                .and("connect.user_id").is(connectId));
        Message message = mongoTemplate.findOne(queryMy, Message.class);
        List<ConnectItem> connect = message.getConnect();
        Integer number = 0;
        for (ConnectItem connectItem : connect) {
            if(connectItem.getUserId().equals(connectId)){
                number = connectItem.getNumber();
            }
        }
        Update updateMy = new Update()
                .push("connect.$.message", messageItem)
                .set("connect.$.number",number+1);//插入到connect中的message，们想要在匹配的数组元素中执行此操作
        mongoTemplate.findAndModify(queryMy, updateMy, Message.class);
        return ResponseResult.OkResult();
    }
    @Override
    public ResponseResult getById(String userId) {
        if(userId == null){
            return ResponseResult.ErrorResult(AppHttpCode.DATA_NULL);
        }
        //设置查询条件
        Criteria criteria = Criteria.where("user_id")
                .is(MessageConstant.CUSTOMER_SERVICE);
        //设置查询条件
        Query query = new Query(criteria);
        //查询
        Message message = mongoTemplate.findOne(query, Message.class);
        if(message == null){
            return ResponseResult.ErrorResult(AppHttpCode.MONGODB_DATA_NULL);
        }
        return ResponseResult.OkResult(message);
    }

    @Override
    public ResponseResult deleteById(String userId) {
        if(userId == null){
            return ResponseResult.ErrorResult(AppHttpCode.DATA_NULL);
        }
        Criteria criteria = Criteria.where("user_id")
                .is(MessageConstant.CUSTOMER_SERVICE)
                .and("connect.user_id").is(userId);
        Query query = new Query(criteria);
        mongoTemplate.remove(query);
        return ResponseResult.OkResult();
    }

    @Override
    public ResponseResult uploadAvatar(MultipartFile file,HttpServletRequest request) {
        if(file==null){
            return ResponseResult.ErrorResult(AppHttpCode.DATA_NULL);
        }
        String[] split = file.getOriginalFilename().split("\\.");
        String contentType = split[split.length-1];
        String uuid = String.valueOf(UUID.randomUUID());  //使用uuid获得文件的扩展名
        String fileName = uuid+"."+contentType;
        try {
            MinIOUtils.uploadFile(BucketNameConstant.ADMIN_MESSAGE_IMG,file,fileName,contentType);  //反斜杠是一个转义字符，所以需要使用两个反斜杠来表示一个实际的点
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return ResponseResult.ErrorResult(AppHttpCode.MINIO_UPLOAD_FAIL);
        }
        String imgURL = MinIOUtils.getBasisUrl(BucketNameConstant.ADMIN_MESSAGE_IMG, fileName);

        return ResponseResult.OkResult(imgURL);
    }

    @Override
    public ResponseResult getUserInfo(String userId) {
        if(MessageConstant.DEFAULT_USER_ID.equals(userId)){  //草稿箱
            return ResponseResult.OkResult("草稿箱");
        }
        ResponseResult result = authFeign.getUserInfoById(userId);
        return result;
    }

    @Override
    public ResponseResult getAuditInfo(String userId) {
        return auditFeign.getAuditInfo(userId);
    }

    @Override
    public ResponseResult clearNumber(String userId) {
        if(userId == null){
            return ResponseResult.ErrorResult(AppHttpCode.DATA_NULL);
        }
        Query query = new Query(Criteria.where("user_id").is(MessageConstant.CUSTOMER_SERVICE)
                .and("connect.user_id").is(userId));
        Update update = new Update();
        update.set("connect.$.number",MessageConstant.NUMBER_CLEAR);
        //查询
        mongoTemplate.updateFirst(query,update,Message.class);
        return ResponseResult.OkResult();
    }

    @Override
    public ResponseResult sendMessage(String userId, MessageItem messageItem) {
        System.out.println(messageItem);
        messageItem.setTime(DateTimeUtils.createNowTime());
        //保存自己的消息
        saveMessage(MessageConstant.CUSTOMER_SERVICE,userId,messageItem);
        // 保存用户的消息
        com.job.client.message.pojo.MessageItem messageItem1 = new com.job.client.message.pojo.MessageItem();
        BeanUtils.copyProperties(messageItem,messageItem1);
        messageItem1.setStatus(MessageConstant.CONTENT_OTHER_STATUS);
        messageFeign.saveMessage(messageItem1,userId,MessageConstant.BOSS_CONNECT_ID);
        return ResponseResult.OkResult();
    }

    @Override
    public ResponseResult sendScreenshot(String base64) {
        if(base64 == null){
            return ResponseResult.ErrorResult(AppHttpCode.DATA_NULL);
        }
        String string1 = base64.split(":")[1];
        String string2[] = string1.split(";");
        String contentType =  string2[0];
        String fileName =  UUID.randomUUID() + "." + string2[0].split("/")[1];
        byte[] bytes = Base64.getDecoder().decode(string2[1].split(",")[1]);
        InputStream inputStream = new ByteArrayInputStream(bytes);
        try {
            MinIOUtils.uploadFile(BucketNameConstant.ADMIN_MESSAGE_IMG,fileName,inputStream,contentType);
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            new MyselfException(201,"minio上传截图图片失败");
        }
        String basisUrl = MinIOUtils.getBasisUrl(BucketNameConstant.ADMIN_MESSAGE_IMG, fileName);
        return ResponseResult.OkResult(basisUrl);
    }
    // 推送消息到webSocket
    public void pushMessage(String cid,String data){
        ResponseResult result = webSocketFeign.pushMessage(cid, data);
        if(result.getCode() != 200){
            log.error("webSocker推送消息失败");
        }
    }
}
